---@type {}
function class(super)
    local cls = {}
    cls.__super = super
    cls.__class = cls
    cls.hashCode = string.match(tostring(cls), "0x.+")
    ---@return {}
    function cls.new(self, ...)
        local instance = metaProperty(cls)
        if instance.ctor then
            instance:ctor(...)
        end
        return instance
    end
    return cls
end
local function superPropertyFind(cls, k)
    while cls do
        local f = cls[k]
        if f then
            return f
        end
        cls = cls.__super
    end
end

local function findFunc(bExtend, cls, newClass, k)
    local f
    if bExtend then
        f = rawget(cls, k)
    else
        f = rawget(newClass, k) or superPropertyFind(cls, k)
    end
    return f
end

function metaProperty(cls, bExtend)
    local newClass = {}
    local proto = {
        __index = function(self, k)
            local _get = findFunc(bExtend, cls, newClass, "_get")
            if _get then
                return _get(self, k)
            end
            local f = findFunc(bExtend, cls, newClass, k)
            if f then
                if type(f) == "table" then
                    local _get = f["_get"]
                    if _get then
                        return _get(self, k)
                    end
                end
                return f
            end
        end,
        __newindex = function(self, k, v)
            local __set = findFunc(bExtend, cls, newClass, "_set")
            if __set then
                return __set(self, k)
            end
            local f = findFunc(bExtend, cls, newClass, k)
            if type(f) == "table" then
                local _set = f["_set"]
                if _set then
                    _set(self, v)
                end
            else
                if bExtend then
                    rawset(cls, k, v)
                else
                    rawset(newClass, k, v)
                end
            end
        end
    }
    return setmetatable(newClass, proto)
end
